﻿using DimensionsHelper.LanguageService.Syntax;

namespace DimensionsHelper.LanguageService;

public partial class Parser
{
    private const string ObjectMemberStart = "Default、ReadOnly、WriteOnly、Nullable、Property、Function 或 Sub";

    /// <summary>
    ///     行标签定义
    /// </summary>
    private LabelDeclaration ParseLabel(Identifier identifierName)
    {
        LabelDeclaration label = NodeFactory.CreateLabelDeclaration(null, identifierName);
        return FinishNode(label, GetStartPoint(identifierName));
    }

    /// <summary>
    ///     本地变量声明
    /// </summary>
    /// <param name="nameIdentifier">名称标识符</param>
    private VariableDeclaration ParseVariableDeclaration(Identifier nameIdentifier)
    {
        VariableDeclaration decl = NodeFactory.CreateVariableDeclaration(null, nameIdentifier);
        return FinishNode(decl, GetStartPoint(nameIdentifier));
    }


    /// <summary>
    ///     本地数组声明
    /// </summary>
    /// <param name="nameIdentifier">名称标识符</param>
    private ArrayDeclaration ParseArrayDeclaration(Identifier nameIdentifier)
    {
        List<IntegerLiteral?> bounds = [];

        while (!Eof())
        {
            if (!CurrentIs(SyntaxKinds.LeftBracketToken) || IsLineEnd())
            {
                break;
            }

            SyntaxToken? next = Expect([SyntaxKinds.Integer, SyntaxKinds.RightBracketToken]);

            if (next == null)
            {
                break;
            }

            if (next.IsNode(SyntaxKinds.RightBracketToken))
            {
                bounds.Add(null);
            }
            else
            {
                bounds.Add(ParseInteger());
                Expect(SyntaxKinds.RightBracketToken);
            }

            if (IsLineEnd() || !TryParse(SyntaxKinds.LeftBracketToken))
            {
                break;
            }
        }

        ArrayDeclaration decl = NodeFactory.CreateArrayDeclaration(null, nameIdentifier, bounds);
        return FinishNode(decl, GetStartPoint(nameIdentifier));
    }


    /// <summary>
    ///     解析单个 本地变量 或 数组 声明
    /// </summary>
    private VariableDeclaration ParseVariableOrArrayDeclaration()
    {
        Identifier localName = ParseIdentifierName();
        return TryParse(SyntaxKinds.LeftBracketToken)
            ? ParseArrayDeclaration(localName)
            : ParseVariableDeclaration(localName);
    }


    /// <summary>
    ///     Dim 声明语句
    /// </summary>
    /// <remarks>
    ///     <code>
    ///         Dim var[, var1[[Bound]...]...]
    ///     </code>
    /// </remarks>
    private DimStatement ParseDimStatement()
    {
        SyntaxToken dimKeywordToken = GetToken();
        DimStatement stat = NodeFactory.CreateDimStatement(null, dimKeywordToken);

        while (!IsLineEnd())
        {
            SourceNode next = Next();
            // Id或关键字，在ParseIdentifierName方法中判断是否为当前上下文中的关键字
            if (next.IsIdentifier || next.IsKeywordToken())
            {
                stat.AddDeclaration(ParseVariableOrArrayDeclaration());

                if (!IsLineEnd())
                {
                    Expect(SyntaxKinds.CommaToken);
                }
            }
            else
            {
                Raise(DiagnosticDescriptors.UnexpectedToken, IdentifierName);
            }
        }

        return FinishNode(stat, GetStartPoint(dimKeywordToken));
    }


    /// <summary>
    ///     本地常量声明
    /// </summary>
    /// <remarks>
    ///     <code>
    ///         Const VarName = InitializeExpression
    ///     </code>
    /// </remarks>
    private ConstantDeclaration ParseConstantDeclaration()
    {
        SyntaxToken constKeywordToken = GetToken();
        Identifier identifierName = ExpectIdentifier();

        // =
        if (!IsLineEnd())
        {
            Expect(SyntaxKinds.EqualToken);
        }

        Expression? initializer = null;

        if (!IsLineEnd())
        {
            initializer = ParseExpression();

            if (!Expression.IsConstantExpression(initializer))
            {
                Raise(DiagnosticDescriptors.UnexpectedToken,
                    initializer, "常量");
            }
        }

        ConstantDeclaration decl =
            NodeFactory.CreateConstantDeclaration(null, constKeywordToken, identifierName, initializer);
        return FinishNode(decl, GetStartPoint(constKeywordToken));
    }


    /// <summary>
    ///     函数声明
    /// </summary>
    /// <remarks>
    ///     <code>
    /// (Function | Sub) FunctionName([ParameterList])
    ///     [Body]
    /// End (Function | Sub)
    /// </code>
    /// </remarks>
    private FunctionDeclaration ParseFunctionDeclaration()
    {
        SyntaxToken declareKeywordToken = GetToken();
        Identifier funcName = ExpectIdentifier();
        FunctionDeclaration decl = NodeFactory.CreateFunctionDeclaration(null, declareKeywordToken, funcName, null);
        // (
        SyntaxToken lf = Expect(SyntaxKinds.LeftParenthesisToken,
            reportDiagnostic: !Identifier.IsDefaultOrEmpty(funcName));
        // ParameterList
        if (!lf.IsEmpty)
        {
            while (!IsLineEnd())
            {
                SourceNode next = Next();

                if (next.IsNode(SyntaxKinds.RightParenthesisToken))
                {
                    break;
                }

                if (next.IsIdentifier || next.IsKeywordToken())
                {
                    decl.AddParameter(ParseVariableOrArrayDeclaration());
                    // 遇到')'退出
                    if (TryParse(SyntaxKinds.RightParenthesisToken))
                    {
                        break;
                    }

                    if (!IsLineEnd())
                    {
                        Expect(SyntaxKinds.CommaToken);
                    }
                }
                else
                {
                    Raise(DiagnosticDescriptors.UnexpectedToken, IdentifierName);
                }
            }
        }

        // Body
        decl.Update(ParseBlock([SyntaxKinds.EndKeywordToken]));

        ExpectContinuousTokens([SyntaxKinds.EndKeywordToken, declareKeywordToken.Kind], true);
        return FinishNode(decl, GetStartPoint(declareKeywordToken));
    }


    /// <summary>
    ///     读取全限定名，中间使用 '.' 分隔
    /// </summary>
    private QualifiedName ParseQualifiedName(Identifier firstName)
    {
        QualifiedName qualifiedName = NodeFactory.CreateQualifiedName(null, firstName);

        while (!IsLineEnd())
        {
            if (Optional(SyntaxKinds.DotToken) == null)
            {
                break;
            }

            qualifiedName.AddMemberName(ExpectIdentifier());
        }

        return FinishNode(qualifiedName, GetStartPoint(firstName));
    }


    private List<QualifiedName> ParseQualifiedNameList()
    {
        List<QualifiedName> names = new();

        while (!IsLineEnd())
        {
            if (names.Count > 0)
            {
                Expect(SyntaxKinds.CommaToken);
            }

            SourceNode next = Next();

            if (next.IsIdentifier)
            {
                names.Add(ParseQualifiedName(ParseIdentifierName()));
            }
            else
            {
                Raise(DiagnosticDescriptors.UnexpectedToken, IdentifierName);
            }
        }

        return names;
    }


    /// <summary>
    ///     类型绑定节点
    /// </summary>
    /// <remarks>
    ///     <code>
    ///         As QualifiedName[[]...]
    ///     </code>
    /// </remarks>
    private TypeBinding ParseTypeBinding(SyntaxToken asKeywordToken)
    {
        Identifier partName = ExpectIdentifier(true);
        QualifiedName qualifiedName = QualifiedName.Default;

        if (!Identifier.IsDefaultOrEmpty(partName))
        {
            qualifiedName = ParseQualifiedName(partName);
        }

        int rank = 0;

        while (!IsLineEnd())
        {
            // [
            if (TryParse(SyntaxKinds.LeftBracketToken))
            {
                Expect(SyntaxKinds.RightBracketToken);
                ++rank;
            }
            else
            {
                break;
            }
        }

        TypeBinding binding = NodeFactory.CreateTypeBinding(null, asKeywordToken, qualifiedName);
        binding.Rank = rank;
        return FinishNode(binding, GetStartPoint(asKeywordToken));
    }


    private void ParseTypeBinding(BindableSignature signature)
    {
        if (!IsLineEnd() && TryParse(SyntaxKinds.AsKeywordToken))
        {
            signature.Update(ParseTypeBinding(GetToken()));
        }
    }


    private void ParseTypeBinding(SignatureWithParameters signatureWithParameters)
    {
        if (!IsLineEnd() && TryParse(SyntaxKinds.AsKeywordToken))
        {
            signatureWithParameters.Update(ParseTypeBinding(GetToken()));
        }
    }


    /// <summary>
    ///     常量签名，可以不初始化
    /// </summary>
    /// <remarks>
    ///     <code>
    /// Const VarName As TypeBinding[ = Initializer]
    /// </code>
    /// </remarks>
    private ConstantSignature ParseConstantSignature()
    {
        SyntaxToken constKeywordToken = GetToken();
        Identifier identifierName = ExpectIdentifier(true);
        ConstantSignature signature =
            NodeFactory.CreateConstantSignature(null, constKeywordToken, identifierName, null);

        // As
        ParseTypeBinding(signature);

        // =
        if (Optional(SyntaxKinds.EqualToken) != null && !IsLineEnd())
        {
            // init
            Expression init = ParseExpression();
            signature.Update(init);
            if (!Expression.IsConstantExpression(init))
            {
                Raise(DiagnosticDescriptors.UnexpectedToken,
                    init, "常量");
            }
        }

        return FinishNode(signature, GetStartPoint(constKeywordToken));
    }


    /// <summary>
    ///     参数签名，只能用在 .d.mrs 文件中
    /// </summary>
    /// <remarks>
    ///     <code>
    /// [ParamArray | Optional] ParameterName As QualifiedName[[]...][ = DefaultValue]
    /// </code>
    /// </remarks>
    private ParameterSignature ParseParameterSignature()
    {
        SourceNode startNode = GetCurrentReportNode();

        SyntaxToken? paramArrayKeywordToken = null;
        SyntaxToken? optionalKeywordToken = null;

        while (CurrentIsOneOf(SyntaxKinds.OptionalKeywordToken, SyntaxKinds.ParamArrayKeywordToken))
        {
            if (CurrentIs(SyntaxKinds.OptionalKeywordToken))
            {
                if (optionalKeywordToken != null)
                {
                    break;
                }

                optionalKeywordToken = GetToken();
            }
            else
            {
                if (paramArrayKeywordToken != null)
                {
                    break;
                }

                paramArrayKeywordToken = GetToken();
            }

            Next();
        }

        Identifier identifierName = ParseIdentifierName(true);
        ParameterSignature signature = NodeFactory.CreateParameterSignature(null, identifierName, null, null, null);
        // As
        ParseTypeBinding(signature);

        // =
        if (TryParse(SyntaxKinds.EqualToken))
        {
            SyntaxToken equalToken = GetToken();
            if (!IsLineEnd())
            {
                signature.Update(equalToken, ParseExpression());
            }
        }

        if (paramArrayKeywordToken != null)
        {
            signature.AddModifier(paramArrayKeywordToken);
        }

        if (optionalKeywordToken != null)
        {
            signature.AddModifier(optionalKeywordToken);
        }

        return FinishNode(signature, GetStartPoint(startNode));
    }


    private void ParseParameterSignatureList(SignatureWithParameters signatureWithParameters)
    {
        while (!IsLineEnd())
        {
            SourceNode next = Next();
            // )
            if (next.IsNode(SyntaxKinds.RightParenthesisToken))
            {
                break;
            }

            // Optional | ParamArray | Identifier
            if (next.IsOneOfNode(SyntaxKinds.OptionalKeywordToken, SyntaxKinds.ParamArrayKeywordToken,
                    SyntaxKinds.Identifier) || next.IsKeywordToken())
            {
                signatureWithParameters.AddParameter(ParseParameterSignature());
                Expect([SyntaxKinds.CommaToken, SyntaxKinds.RightParenthesisToken]);
                // )
                if (CurrentIs(SyntaxKinds.RightParenthesisToken) || IsLineEnd())
                {
                    break;
                }
            }
            else
            {
                Raise(DiagnosticDescriptors.UnexpectedToken, "Optional、ParamArray 或 标识符");
            }
        }
    }


    /// <summary>
    ///     读取参数签名列表 -> 如果当前位置的下一个是左括号'('，开始读取，到')'或行尾结束。
    /// </summary>
    private void ParseParameterSignatureListWithParen(SignatureWithParameters signatureWithParameters,
        bool reportDiagnostic)
    {
        SyntaxToken lf = Expect(SyntaxKinds.LeftParenthesisToken, reportDiagnostic: reportDiagnostic);

        if (lf.IsEmpty)
        {
            return;
        }

        ParseParameterSignatureList(signatureWithParameters);
        ExpectCurrent(SyntaxKinds.RightParenthesisToken);
    }


    /// <summary>
    ///     函数签名，只能在 .d.mrs 文件中使用
    /// </summary>
    /// <remarks>
    ///     <code>
    /// (Function | Sub) FunctionName([Parameter1[, Parameter2]...]) [As TypeBinding]
    /// </code>
    /// </remarks>
    private FunctionSignature ParseFunctionSignature()
    {
        SyntaxToken declareKeywordToken = GetToken();
        Identifier identifierName = ExpectIdentifier(true);
        FunctionSignature signature =
            NodeFactory.CreateFunctionSignature(null, declareKeywordToken, identifierName, null, null);
        // (
        ParseParameterSignatureListWithParen(signature, !Identifier.IsDefaultOrEmpty(identifierName));
        // As
        ParseTypeBinding(signature);

        return FinishNode(signature, GetStartPoint(declareKeywordToken));
    }

    /// <summary>
    ///     枚举成员签名
    /// </summary>
    /// <remarks>
    ///     <code>
    ///         EnumName[ = IntegerNumber]
    ///     </code>
    /// </remarks>
    private EnumMemberSignature ParseEnumMemberSignature()
    {
        Identifier name = ParseIdentifierName();
        SyntaxPoint start = GetStartPoint(name);

        EnumMemberSignature signature = NodeFactory.CreateEnumMemberSignature(null, name, null, null);
        // =
        if (!TryParse(SyntaxKinds.EqualToken))
        {
            return FinishNode(signature, start);
        }

        SyntaxToken equalToken = GetToken();
        if (IsLineEnd())
        {
            return FinishNode(signature, start);
        }

        Expression initExpr = ParseExpression();
        // 正数
        if (initExpr.Is<IntegerLiteral>(SyntaxKinds.Integer, out IntegerLiteral? integer))
        {
            signature.Update(equalToken, integer);
        }
        // 负数
        else if (NodeConverter.TryConvertNegativeInteger(initExpr, out integer))
        {
            signature.Update(equalToken, integer);
        }
        // 无效值
        else
        {
            Raise(DiagnosticDescriptors.UnexpectedToken, initExpr.Span, "整数");
        }

        return FinishNode(signature, start);
    }


    /// <summary>
    ///     枚举类型签名
    /// </summary>
    /// <remarks>
    ///     <code>
    /// Enum EnumTypeName
    ///     [EnumMembers]
    /// End Enum
    /// </code>
    /// </remarks>
    private EnumSignature ParseEnumSignature()
    {
        SyntaxToken enumKeywordToken = GetToken();
        Identifier identifierName = ExpectIdentifier(true);
        EnumSignature signature = NodeFactory.CreateEnumSignature(null, enumKeywordToken, identifierName);
        ParseBlockWithSeparator([SyntaxKinds.EndKeywordToken], SyntaxKinds.Unknown,
            ParseEnumMemberSignature, signature.AddMember);
        ExpectContinuousTokens([SyntaxKinds.EndKeywordToken, SyntaxKinds.EnumKeywordToken], true);
        return FinishNode(signature, GetStartPoint(enumKeywordToken));
    }


    private List<SyntaxToken> ParseModifiers(SyntaxKinds[] stopTokens)
    {
        List<SyntaxToken> modifiers = new();

        while (!IsLineEnd())
        {
            if (CurrentIsOneOf(stopTokens))
            {
                break;
            }

            if (!GetCurrentNode().IsTokenNode)
            {
                Raise(DiagnosticDescriptors.InvalidModifier);
            }
            else
            {
                modifiers.Add(GetToken());
            }

            Next();
        }

        return modifiers;
    }


    /// <summary>
    ///     属性签名
    /// </summary>
    /// <remarks>
    ///     [ReadOnly | WriteOnly | Default | Nullable] Property PropertyName([ParameterList]) As TypeBinding
    /// </remarks>
    private PropertySignature ParsePropertySignature(SyntaxPoint start, List<SyntaxToken>? modifiers)
    {
        SyntaxToken propertyKeywordToken = GetToken();
        Identifier propertyName = ExpectIdentifier(true, !propertyKeywordToken.IsEmpty);
        PropertySignature signature = NodeFactory.CreatePropertySignature(null, null, propertyKeywordToken,
            propertyName, null, null);
        // modifiers
        if (modifiers != null)
        {
            foreach (SyntaxToken token in modifiers)
            {
                if (!signature.TryAddModifier(token))
                {
                    Raise(DiagnosticDescriptors.InvalidModifier, token.Span);
                }
            }
        }

        // (
        ParseParameterSignatureListWithParen(signature, !Identifier.IsDefaultOrEmpty(propertyName));
        // As
        ParseTypeBinding(signature);

        return FinishNode(signature, start);
    }


    /// <summary>
    ///     解析类或接口的成员方法签名
    /// </summary>
    /// <remarks>
    ///     <code>
    /// (Sub | Function) MethodName([ParameterList])[ As BindingType]
    /// </code>
    /// </remarks>
    private MethodSignature ParseMethodSignature(List<SyntaxToken>? modifiers)
    {
        SyntaxToken declareKeywordToken = GetToken();
        Identifier methodName = ExpectIdentifier(true);
        // signature
        MethodSignature signature = NodeFactory.CreateMethodSignature(null, declareKeywordToken,
            null, methodName, null, null);

        if (modifiers != null)
        {
            foreach (SyntaxToken modifier in modifiers)
            {
                if (signature.ContainsModifier(modifier.Kind))
                {
                    Raise(DiagnosticDescriptors.RepetitiveModifier, modifier.Span);
                }
                else if (!signature.TryAddModifier(modifier))
                {
                    Raise(DiagnosticDescriptors.InvalidModifier, modifier.Span);
                }
            }
        }

        // parameters
        ParseParameterSignatureListWithParen(signature, !Identifier.IsDefaultOrEmpty(methodName));
        // As
        ParseTypeBinding(signature);

        return FinishNode(signature, GetStartPoint(declareKeywordToken));
    }


    /// <summary>
    ///     解析 接口 或 类 的定义成员
    /// </summary>
    private void ParseObjectTypeMember(ObjectTypeSignature signature)
    {
        while (!Eof())
        {
            SourceNode node = Next();

            if (node.IsNode(SyntaxKinds.EndKeywordToken))
            {
                break;
            }

            switch (node)
            {
                case { Kind: SyntaxKinds.SubKeywordToken }:
                case { Kind: SyntaxKinds.FunctionKeywordToken }:
                    signature.AddMethod(ParseMethodSignature(null));
                    break;

                case { Kind: SyntaxKinds.PropertyKeywordToken }:
                    SourceNode currentNode = GetCurrentReportNode();
                    signature.AddProperty(ParsePropertySignature(GetStartPoint(currentNode), null));
                    break;

                case { Kind: SyntaxKinds.ConstKeywordToken }:
                    ConstantSignature constant = ParseConstantSignature();
                    if (signature.Is<ClassSignature>(SyntaxKinds.ClassSignature,
                            out ClassSignature? classSignature))
                    {
                        classSignature.AddConstant(constant);
                    }
                    else
                    {
                        Raise(DiagnosticDescriptors.CannotDeclareConstantInInterface,
                            constant.DeclareKeywordToken.Span);
                    }

                    break;

                default:
                    SyntaxPoint start = GetCurrentStartPoint();
                    List<SyntaxToken>? modifiers;
                    // Modifiers
                    if (SyntaxFacts.IsModifier(node.Kind))
                    {
                        modifiers = ParseModifiers([
                            SyntaxKinds.PropertyKeywordToken, SyntaxKinds.FunctionKeywordToken,
                            SyntaxKinds.SubKeywordToken
                        ]);
                    }
                    else
                    {
                        Raise(DiagnosticDescriptors.UnexpectedToken, ObjectMemberStart);
                        SkipLine();
                        break;
                    }

                    // 换行时，结束
                    if (IsLineEnd())
                    {
                        break;
                    }

                    // Property
                    if (CurrentIs(SyntaxKinds.PropertyKeywordToken))
                    {
                        signature.AddProperty(ParsePropertySignature(start, modifiers));
                    }
                    else
                    {
                        signature.AddMethod(ParseMethodSignature(modifiers));
                    }

                    break;
            }
        }
    }


    /// <summary>
    ///     接口签名
    /// </summary>
    /// <remarks>
    ///     <code>
    /// Interface InterfaceName
    ///     [Inherits QualifiedName[, QualifiedName...]]
    ///     [Members]
    /// End Interface
    /// </code>
    /// </remarks>
    private InterfaceSignature ParseInterfaceSignature()
    {
        SyntaxToken interfaceKeywordToken = GetToken();
        Identifier interfaceName = ExpectIdentifier(true);
        // signature
        InterfaceSignature signature = NodeFactory.CreateInterfaceSignature(null, interfaceKeywordToken,
            interfaceName, null, null, null);
        // inherits
        if (TryParse(SyntaxKinds.InheritsKeywordToken, allowNewLine: true))
        {
            List<QualifiedName> inheritList = ParseQualifiedNameList();
            foreach (QualifiedName name in inheritList)
            {
                signature.Inherit(name);
            }
        }

        // Members
        ParseObjectTypeMember(signature);

        // End Interface
        ExpectContinuousTokens([SyntaxKinds.EndKeywordToken, SyntaxKinds.InterfaceKeywordToken],
            true);

        return FinishNode(signature, GetStartPoint(interfaceKeywordToken));
    }


    /// <summary>
    ///     类签名
    /// </summary>
    /// <remarks>
    ///     <code>
    /// Class ClassName
    ///     [Inherits BaseClassQualifiedName]
    ///     [Implements [QualifiedName[, QualifiedName1]...]]
    ///     [Class Members]
    /// End Class
    /// </code>
    /// </remarks>
    private ClassSignature ParseClassSignature()
    {
        SyntaxToken classKeywordToken = GetToken();
        Identifier className = ExpectIdentifier(true);
        // signature
        ClassSignature signature = NodeFactory.CreateClassSignature(null, classKeywordToken,
            className, null, null, null, null, null);
        // inherits
        if (TryParse(SyntaxKinds.InheritsKeywordToken, allowNewLine: true))
        {
            List<QualifiedName> inheritsList = ParseQualifiedNameList();
            foreach (QualifiedName inherit in inheritsList)
            {
                signature.Inherit(inherit);
            }
        }

        // implements
        if (TryParse(SyntaxKinds.ImplementsKeywordToken, allowNewLine: true))
        {
            List<QualifiedName> implementList = ParseQualifiedNameList();
            foreach (QualifiedName impl in implementList)
            {
                signature.Implement(impl);
            }
        }

        // members
        ParseObjectTypeMember(signature);

        // End Class
        ExpectContinuousTokens([SyntaxKinds.EndKeywordToken, SyntaxKinds.ClassKeywordToken], true);

        return FinishNode(signature, GetStartPoint(classKeywordToken));
    }


    /// <summary>
    ///     模块签名
    /// </summary>
    /// <remarks>
    ///     <code>
    /// Module ModuleName[.Name1...]
    ///     [Module Members]
    /// End Module
    /// </code>
    /// </remarks>
    private ModuleSignature ParseModuleSignature()
    {
        SyntaxToken moduleKeywordToken = GetToken();
        Identifier moduleName = ExpectIdentifier(true);
        QualifiedName qualifiedName = ParseQualifiedName(moduleName);

        // signature
        ModuleSignature signature = NodeFactory.CreateModuleSignature(null, moduleKeywordToken, qualifiedName,
            null,
            null, null, null, null);

        const string moduleMemberStarts = "Interface、Class、Enum、Function、Sub 或 Const";

        while (!Eof())
        {
            SourceNode next = Next();

            if (next.IsNode(SyntaxKinds.EndKeywordToken))
            {
                break;
            }

            switch (next)
            {
                case { Kind: SyntaxKinds.EnumKeywordToken }:
                    signature.AddEnum(ParseEnumSignature());
                    break;

                case { Kind: SyntaxKinds.ClassKeywordToken }:
                    signature.AddClass(ParseClassSignature());
                    break;

                case { Kind: SyntaxKinds.InterfaceKeywordToken }:
                    signature.AddInterface(ParseInterfaceSignature());
                    break;

                case { Kind: SyntaxKinds.ConstKeywordToken }:
                    signature.AddConstant(ParseConstantSignature());
                    break;

                case { Kind: SyntaxKinds.NullableKeywordToken }:
                case { Kind: SyntaxKinds.FunctionDeclaration }:
                case { Kind: SyntaxKinds.SubKeywordToken }:
                    signature.AddFunction(ParseFunctionSignature());
                    break;

                default:
                    Raise(DiagnosticDescriptors.UnexpectedToken, moduleMemberStarts);
                    SkipLine();
                    break;
            }
        }

        // End Module
        ExpectContinuousTokens([SyntaxKinds.EndKeywordToken, SyntaxKinds.ModuleKeywordToken],
            true);

        return FinishNode(signature, GetStartPoint(moduleKeywordToken));
    }


    private Statement ParseDeclareStatement()
    {
        SourceNode node = GetCurrentNode();
        return node switch
        {
            { Kind: SyntaxKinds.ModuleKeywordToken } => ParseModuleSignature(),
            { Kind: SyntaxKinds.ClassKeywordToken } => ParseClassSignature(),
            { Kind: SyntaxKinds.InterfaceKeywordToken } => ParseInterfaceSignature(),
            { Kind: SyntaxKinds.EnumKeywordToken } => ParseEnumSignature(),
            {
                Kind: SyntaxKinds.FunctionKeywordToken or SyntaxKinds.SubKeywordToken
                or SyntaxKinds.NullableKeywordToken
            } => ParseFunctionSignature(),
            { Kind: SyntaxKinds.ConstKeywordToken } => ParseConstantSignature(),
            _ => CreateEmptyExpressionStatement(DiagnosticDescriptors.InvalidToken)
        };
    }
}